/*
 *  Copyright 2009 Advanced Industrial Science and Technology (AIST).
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*! \file
 *  \brief
 */
#pragma once

#include <thrust/detail/type_traits.h>

namespace thrust {

// forward declarations of edge_iter
template <typename Iter
          , typename EdgeDescriptor
          , typename CalledSpace>
class edge_iter;

// forward declarations of undirected_out_edge_iter
template <typename EdgeIter
          , typename VertexDescriptor
          , typename EdgeDescriptor
          , typename CalledSpace>
class undirected_out_edge_iter;

// forward declarations of adjacency_iterator
template <typename Graph
          , typename Vertex
          , typename OutEdgeIter>
struct adjacency_iter;


namespace detail {

namespace device {

// edge_iter prototype
template <typename Iter
          , typename EdgeDescriptor
          , typename CalledSpace>
inline __device__
typename dereference_result< edge_iter<Iter
                                       , EdgeDescriptor
                                       , CalledSpace> >::type
dereference( const edge_iter<Iter
             , EdgeDescriptor
             , CalledSpace>& iter);

// undirected_out_edge_iter prototype
template <typename EdgeIter
          , typename VertexDescriptor
          , typename EdgeDescriptor
          , typename CalledSpace>
inline __host__ __device__
typename dereference_result< undirected_out_edge_iter<EdgeIter
                                                      , VertexDescriptor
                                                      , EdgeDescriptor
                                                      , CalledSpace> >::type
dereference( const undirected_out_edge_iter<EdgeIter
             , VertexDescriptor
             , EdgeDescriptor
             , CalledSpace>& iter);
  
// adjacency_iter prototype
template <typename Graph
          , typename Vertex
          , typename OutEdgeIter>
inline __host__ __device__
typename dereference_result< adjacency_iter<Graph
                                            , Vertex
                                            , OutEdgeIter> >::type
dereference( const adjacency_iter<Graph
             , Vertex
             , OutEdgeIter>& iter);

} // end namespace device

} // end namespace detail

} // end namespace thrust
